import moment from 'moment';

export function delArrItem(arr, item) {
    let i = arr.indexOf(item);
    if (i > -1) {
        arr.splice(i, 1);
    }
    return arr;
}

/**
 * 深度克隆数据,包括对象，数组，map
 * @param {*} obj 对象，数组，map
 */
export function deepCopy(obj) {
    if (!isObject(obj) && !isMap(obj)) {
        console.error('obj不是一个对象也不是map！');
        return obj;
    }

    let cloneObj;
    if (isMap(obj)) {
        cloneObj = new Map();
        for (let key of obj.keys()) {
            let value = obj.get(key);
            if (isMap(value) || isObject(value)) {
                cloneObj.set(key, deepCopy(value));
            }
        }
    } else if (typeof obj === 'function') {
        cloneObj = obj;
    } else {
        cloneObj = Array.isArray(obj) ? [] : {};
        if (obj instanceof HTMLElement) {
            cloneObj = obj.cloneNode(true);
        } else {
            for (let key in obj) {
                if (obj.hasOwnProperty(key)) {
                    cloneObj[key] =
                        isMap(obj[key]) || isObject(obj[key])
                            ? deepCopy(obj[key])
                            : obj[key];
                }
            }
        }
    }
    return cloneObj;
}

/**
 * 深拷贝，当obj为map时转为一维数组
 * @param {*} obj
 */
export function deepCopyMapToArray(obj) {
    if (!isObject(obj)) {
        console.error('obj 不是一个对象！');
        return obj;
    }

    function isObject(o) {
        return (typeof o === 'object' || typeof o === 'function') && o !== null;
    }

    if (obj instanceof Map) {
        let arr = [];
        for (let value of obj.values()) {
            arr.push(value);
        }
        obj = arr;
    }

    let cloneObj = Array.isArray(obj) ? [] : {};
    for (let key in obj) {
        cloneObj[key] = isObject(obj[key])
            ? deepCopyMapToArray(obj[key])
            : obj[key];
    }

    return cloneObj;
}

// 判断某个元素是否在指定数组里面
export function isBelong(item, arr) {
    var flag = false;
    if (arr.length) {
        var strArr = JSON.stringify(arr);
        var strItem = JSON.stringify(item);
        if (strArr.indexOf(strItem) > -1) {
            flag = true;
            return flag;
        }
    }
    return flag;
}

//检查一个数组是否包含属于另一个数组
export function isContain(arr1, arr2) {
    for (var i = arr2.length - 1; i >= 0; i--) {
        if (!arr1.includes(arr2[i])) {
            return false;
        }
    }
    return true;
}

/**
 * map转jsonObj
 * @param {*} map
 */
export function mapToObj(map) {
    let obj = Object.create(null);
    for (let [k, v] of map) {
        // We don’t escape the key '__proto__'
        // which can cause problems on older engines
        obj[k] = v;
    }
    return obj;
}

/**
 * jsonObj转map
 * @param {json} obj
 */
export function objToMap(obj) {
    let map = new Map();
    try {
        for (let k of Object.keys(obj)) {
            if (!k || k == 'null') {
                throw new Error('键值不能为空!');
            }
            if (!isNaN(k)) {
                map.set(Number(k), obj[k]);
            } else {
                map.set(k, obj[k]);
            }
        }
    } catch (e) {
        console.error(e.name + ': ' + e.message);
        return null;
    }

    return map;
}

/**
 * 递归查找objects下的子objects转成map
 * @param {Map} map 已经转成了map的objects
 */
export function recursiveObjsToMap(map) {
    for (let value of map.values()) {
        if (value.objects) {
            let childMap = objToMap(value.objects);
            value.objects = childMap;
            recursiveObjsToMap(childMap);
        }
    }
}

/**
 * map集合排序
 * @param {Map} map 需要排序的map
 * @param {String} property 传key表示key排序，或者传value的属性名称
 * @param {Boolean} isDesc 是否降序，默认升序asc
 */
export function sortMap(map, property, isDesc) {
    try {
        let sortedMap = new Map(
            [...map].sort(([k1, v1], [k2, v2]) => {
                if (property === 'key') {
                    if (isNaN(k1)) {
                        throw new Error('键值不是数字，不能排序!');
                    }
                    if (!isDesc) {
                        if (k1 > k2) {
                            return 1;
                        } else {
                            return -1;
                        }
                    } else {
                        if (k2 > k1) {
                            return 1;
                        } else {
                            return -1;
                        }
                    }
                } else {
                    if (isNaN(v1[property])) {
                        throw new Error('不是数字，不能排序！');
                    }
                    if (!isDesc) {
                        if (v1[property] > v2[property]) {
                            return 1;
                        } else {
                            return -1;
                        }
                    } else {
                        if (v2[property] > v1[property]) {
                            return 1;
                        } else {
                            return -1;
                        }
                    }
                }
            })
        );
        return sortedMap;
    } catch (e) {
        console.error(e.name + ': ' + e.message);
        return map;
    }
}

/**
 * 拼接map  将第一个参数后的所有map加到第一个map上; 若key值重复,则对应值将会被覆盖
 * @param {Map} map 用于拼接并返回的map
 * @param {Array<Map>} args 多个map参数的数组 es6 Rest Parameters写法
 */
export function concatMap(map, ...args) {
    let isValidate = true;
    if (!isMap(map)) {
        console.error('参数不是map类型！');
        isValidate = false;
    } else if (args && args.length > 0) {
        for (let i = 0; i < args.length; i++) {
            const arg = args[i];
            if (!isMap(arg)) {
                console.error('包含非map类型参数！');
                break;
            } else {
                for (let [key, value] in arg.entries()) {
                    map.set(key, value);
                }
            }
        }
    }
    return map;
}

/**
 * 判断参数是否是Object类型
 * @param {*} o
 */
function isObject(o) {
    return (
        !isMap(o) &&
        (typeof o === 'object' || typeof o === 'function') &&
        o !== null
    );
}

/**
 * 判断参数是否是Map类型
 * @param {*} obj
 */
export function isMap(obj) {
    if (obj instanceof Map) {
        return true;
    } else {
        return false;
    }
}

function copyProperties(target, source) {
    for (let key of Reflect.ownKeys(source)) {
        if (key !== 'constructor' && key !== 'prototype' && key !== 'name') {
            let desc = Object.getOwnPropertyDescriptor(source, key);
            Object.defineProperty(target, key, desc);
        }
    }
}
export function isRealNum(val) {
    // 判断是否是数字
    if (typeof val !== 'number') {
        return false;
    }
    // NaN 或数字
    return !isNaN(val);
}

/**
 * 将二维数组转换为一维数组
 * @param {Array} targetArr  转换对象的key
 * @param {Array} source
 */
export function array2arr(targetArr, source) {
    var data = [];
    source.forEach(item => {
        let obj = {};
        for (var i = 0; i < item.length; i++) {
            obj[targetArr[i]] = item[i];
        }
        data.push(obj);
    });
    return data;
}

/**
 * 事件频繁触发时，停止触发wait间隔后执行一次
 * @param {*} fn 回调函数
 * @param {*} wait 间隔时间
 */
export function debounce(fn, wait) {
    var timeout;
    return function() {
        var self = this;
        clearTimeout(timeout);
        timeout = setTimeout(function() {
            fn.apply(self);
        }, wait);
    };
}

/**
 * 格式化时间  可传入格式，默认为YYYY-MM-DD HH:mm:ss
 */
export function formatTime(data, type = 'YYYY-MM-DD HH:mm:ss') {
    if (data && !Number.isNaN(data)) {
        return moment(data).format(type);
    }
    return data;
}

//生产随机id

export function generateNumberID() {
    return parseInt('' + +new Date() + parseInt(Math.random() * 10));
}

// 图片自适应
export function loadImg(className, width, height, maxWidth) {
    var img = document.getElementsByClassName(className)[0];
    if (img) {
        img.style.width = document.documentElement.clientWidth;
        window.addEventListener(
            'resize',
            () => {
                let imgWidth = document.documentElement.clientWidth;
                if (maxWidth) {
                    imgWidth =
                        document.documentElement.clientWidth > maxWidth
                            ? maxWidth
                            : document.documentElement.clientWidth;
                }
                img.style.width = imgWidth + 'px';
            },
            false
        );
        img.style.height =
            (document.documentElement.clientWidth * height) / width + 'px';
    }
}
export function isMobile() {
    let mobile = navigator.userAgent.match(
        /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i
    );
    return mobile != null;
}
